package com.ultra.constraint;

import com.ultra.enums.ConstraintTypeEnum;
import com.ultra.template.content.AcvContext;
import com.ultra.template.content.Argument;
import com.ultra.template.content.Order;
import com.ultra.template.content.Pairs;
import com.ultra.template.parse.Parser;
import com.ultra.validator.Range;
import lombok.Data;

import java.util.Comparator;
import java.util.Map;

/**
 * @author hcUltra
 * @description 算法输入的约束
 * @date 2024/5/2 17:18
 **/
@Data
public class Constraint {
    // 约束类型
    private ConstraintTypeEnum type;
    // 约束的范围
    private Range range;
    // 约束的字符构成
    private String chars;
    // 排序约束的比较器
    private String order = "asc";// 默认升序 asc
    // 约束表达式（应该是可以计算的）
    private String expression;

    private Constraint() {

    }

    public static class Builder {
        private final ConstraintTypeEnum type;
        private Range range;
        private String chars;
        private String order = "asc";
        private String expression;

        public Builder(ConstraintTypeEnum type) {
            this.type = type;
        }

        public Builder range(Range range) {
            this.range = range;
            return this;
        }

        public Builder chars(String chars) {
            this.chars = chars;
            return this;
        }

        public Builder comparator(String order) {
            this.order = order;
            return this;
        }

        public Builder expression(String expression) {
            this.expression = expression;
            return this;
        }

        public Constraint build() {
            Constraint constraint = new Constraint();
            constraint.type = type;
            constraint.range = this.range;
            constraint.chars = this.chars;
            constraint.order = this.order;
            constraint.expression = this.expression;
            return constraint;
        }
    }


    public static void preParseConstraint(AcvContext context, Map<Pairs, Constraint> constraints) {
        constraints.forEach(
                (pairs, constraint) -> {
                    Argument argument = Parser.flatteningMap.get(pairs);
                    if (constraint.type.equals(ConstraintTypeEnum.SIZE)) {
                        argument.setSize(constraint.getRange());
                    } else if (constraint.type.equals(ConstraintTypeEnum.VALUE)) {
                        argument.setValue(constraint.getRange());
                    } else if (constraint.type.equals(ConstraintTypeEnum.ORDER)) {
                        Order order = null;
                        if ("asc".equals(constraint.order)) {
                            order = new Order(true, Comparator.naturalOrder());
                        } else if ("desc".equals(constraint.order)) {
                            order = new Order(false, Comparator.reverseOrder());
                        }
                        assert order != null;
                        argument.setOrder(order);
                    } else if (constraint.type.equals(ConstraintTypeEnum.CHARS)) {
                        argument.setChars(constraint.getChars());
                    } else {
                        // 需要计算的约束，加入到argument
                        context.getToBeEvaluatedConstraints().put(pairs, constraint);
                    }
                }
        );
    }
}
